package com.solution.common.dao.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.solution.common.dao.BaseDao;
import com.solution.common.entity.BaseEntity;
import com.solution.common.exception.BizException;
import com.solution.common.page.PageBean;
import com.solution.common.page.PageParam;

/**
 * @描述: 数据访问层基础支撑类.
 * @作者: WuShuicheng .
 * @创建时间: 2013-7-22,下午4:52:52 .
 * @版本: 1.0 .
 */
public abstract class BaseDaoImpl<T extends BaseEntity> extends SqlSessionDaoSupport implements BaseDao<T> {

	protected static final Logger log = LoggerFactory.getLogger(BaseDaoImpl.class);
	public static final String SQL_INSERT = "insert";
	public static final String SQL_BATCH_INSERT = "batchInsert";
	public static final String SQL_UPDATE = "update";
	public static final String SQL_GET_BY_ID = "getById";
	public static final String SQL_DELETE_BY_ID = "deleteById";
	public static final String SQL_LIST_PAGE = "listPage";
	public static final String SQL_LIST_BY = "listBy";
	public static final String SQL_COUNT_BY_PAGE_PARAM = "countByParam"; // 根据当前分页参数进行统计

	/**
	 * 注入SqlSessionTemplate实例(要求Spring中进行SqlSessionTemplate的配置).<br/>
	 * 可以调用sessionTemplate完成数据库操作.
	 */
	@Autowired
	private SqlSessionTemplate sessionTemplate;
	
	@Autowired
    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {  
        super.setSqlSessionFactory(sqlSessionFactory);  
    }

	
	public long insert(T t) {
		if (t == null) {
			throw new RuntimeException("T is null");
		}
		int result = sessionTemplate.insert(getStatement(SQL_INSERT), t);
		if (result <= 0) {
			throw BizException.DB_INSERT_RESULT_0;
		}
		if (t != null && t.getId() != null && result > 0) {
			return t.getId();
		}
		return result;
	}

	public int insert(List<T> list) {
		if (list == null || list.size() <= 0) {
			return 0;
		}
		int result = sessionTemplate.insert(getStatement(SQL_BATCH_INSERT),
				list);
		if (result <= 0) {
			throw BizException.DB_INSERT_RESULT_0;
		}
		return result;
	}

	public int update(T t) {
		if (t == null) {
			throw new RuntimeException("T is null");
		}
		int result = sessionTemplate.update(getStatement(SQL_UPDATE), t);
		if (result <= 0) {
			throw BizException.DB_UPDATE_RESULT_0;
		}
		return result;
	}

	public int update(List<T> list) {
		if (list == null || list.size() <= 0) {
			return 0;
		}
		int result = 0;
		for (int i = 0; i < list.size(); i++) {
			this.update(list.get(i));
			result += 1;
		}
		if (result <= 0) {
			throw BizException.DB_UPDATE_RESULT_0;
		}
		return result;
	}

	public T getById(long id) {
		return sessionTemplate.selectOne(getStatement(SQL_GET_BY_ID), id);
	}

	public int deleteById(long id) {
		return sessionTemplate.delete(getStatement(SQL_DELETE_BY_ID), id);
	}

	/**
	 * 根据传入的分页标记进行分页查询方法
	 * @param pageParam
	 *            分页参数
	 * @param paramMap
	 *            分页查询参数
	 * @param sqlId
	 *            查询分页数据的sqlid
	 * @param countSqlId
	 *            查询分页条数的sqlid
	 * @author llp
	 * @return PageBean 包含分页参数和分数数据
	 * @date 2017/4/18 4:58
	 */
	@SuppressWarnings("unchecked")
	public PageBean listPage(PageParam pageParam, Map<String, Object> paramMap,
			String sqlId, String countSqlId) {
		if (paramMap == null) {
			paramMap = new HashMap<String, Object>();
		}
		// 统计总记录数
		Integer count = sessionTemplate.selectOne(getStatement(countSqlId),
				paramMap);
		List<Object> list = null;
		if (count != null && count > 0) {
			paramMap.put("offset",(pageParam.getPageNum() - 1) * pageParam.getNumPerPage());
			paramMap.put("limit", pageParam.getNumPerPage());
			list = sessionTemplate.selectList(getStatement(sqlId), paramMap);
		} else {
			list = Collections.EMPTY_LIST;
		}
		return new PageBean(pageParam.getPageNum(), pageParam.getNumPerPage(),count.intValue(), list);
	}

	/**
	 * 分页查询
	 * @param pageParam
	 *            分页参数
	 * @param paramMap
	 *            分页查询参数
	 * @author llp
	 * @return PageBean 包含分页参数和分数数据
	 * @date 2017/4/18 4:58
	 */
	public PageBean listPage(PageParam pageParam, Map<String, Object> paramMap) {
		if (paramMap == null) {
			paramMap = new HashMap<String, Object>();
		}
		Integer count = sessionTemplate.selectOne(
				getStatement(SQL_COUNT_BY_PAGE_PARAM), paramMap);
		List<Object> list = null;
		if (count != null && count > 0) {
			paramMap.put("offset",(pageParam.getPageNum() - 1) * pageParam.getNumPerPage());
			paramMap.put("limit", pageParam.getNumPerPage());
			// 获取分页数据集 , 注切勿换成 sessionTemplate 对象
			list = sessionTemplate.selectList(getStatement(SQL_LIST_PAGE),paramMap);
		} else {
			list = new ArrayList<Object>();
		}
		return new PageBean(pageParam.getPageNum(), pageParam.getNumPerPage(),count, list);
	}

	public List<T> listBy(Map<String, Object> paramMap) {
		return (List) this.listBy(paramMap, SQL_LIST_BY);
	}

	public List<Object> listBy(Map<String, Object> paramMap, String sqlId) {
		if (paramMap == null) {
			paramMap = new HashMap<String, Object>();
		}
		return sessionTemplate.selectList(getStatement(sqlId), paramMap);
	}

	@SuppressWarnings("unchecked")
	public T getBy(Map<String, Object> paramMap) {
		return (T) this.getBy(paramMap, SQL_LIST_BY);
	}

	public T getBy(Map<String, Object> paramMap, String sqlId) {
		if (paramMap == null || paramMap.isEmpty()) {
			return null;
		}
		return sessionTemplate.selectOne(getStatement(sqlId), paramMap);
	}

	public String getStatement(String sqlId) {
		String name = this.getClass().getName();
		StringBuffer sb = new StringBuffer().append(name).append(".")
				.append(sqlId);
		return sb.toString();
	}
	
	public SqlSessionTemplate getSessionTemplate(){
		return sessionTemplate;
	}
	
	public SqlSessionTemplate getSqlSession() {
		return sessionTemplate;
	}

}
